package com.chenfan.process.biz.impl;

import com.alibaba.fastjson.JSONObject;
import com.chenfan.ccp.common.exception.ApiException;
import com.chenfan.ccp.common.result.IResultCode;
import com.chenfan.ccp.common.result.R;
import com.chenfan.ccp.util.tool.JsonUtil;
import com.chenfan.infra.constants.CommonBeanConstants;
import com.chenfan.infra.context.TenantContextHolder;
import com.chenfan.infra.context.UserContextHolder;
import com.chenfan.notify.NotifyClient;
import com.chenfan.notify.dto.DingDTO;
import com.chenfan.notify.dto.NotifyDTO;
import com.chenfan.notify.enums.NotifyProcessEnums;
import com.chenfan.notify.enums.NotifyTypeEnums;
import com.chenfan.notify.vo.NotifyVo;
import com.chenfan.process.common.exception.ProcessResultCode;
import com.chenfan.process.entity.po.ProcessDetailPo;
import com.chenfan.process.util.MathUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author liuming
 * @date 2021/10/8
 */
@Slf4j
@Service
public class NotifyBiz {

    @Autowired
    private NotifyClient notifyClient;

    @Value("${pass.notify.topic}")
    private String notifyMessageTopic;
    @Autowired
    private RocketMQTemplate rocketTemplate;

    public void dealWithNotify(Long approvalId) {
        List<NotifyVo> notifyList = notifyClient.listNotifyByApprovalId(Collections.singletonList(approvalId)).getObj();
        dealWithNotify(notifyList, null);
    }

    public void dealWithNotify(List<NotifyVo> notifyList, ProcessDetailPo processDetailPo) {
        if(!CollectionUtils.isEmpty(notifyList)){
            List<Long> notifyIdList =
                    notifyList.stream().filter(this::isWait).map(NotifyVo::getId).collect(Collectors.toList());

            // TODO 如果当前节点是会签节点, 那么只处理自己的数据
            if (processDetailPo != null && processDetailPo.isCounterSign()) {
                notifyIdList = notifyList.stream()
                        .filter(
                                e -> this.isWait(e) && Objects.equals(UserContextHolder.getUserVo().getUserId(), e.getUserId()))
                        .map(NotifyVo::getId).collect(Collectors.toList());
            }
            log.info("处理之前的:{}, 处理之后的id:{}", JSONObject.toJSONString(notifyList), notifyIdList);
            if (!CollectionUtils.isEmpty(notifyIdList)) {
                // 调用远程接口
                notifyClient.dealNotify(notifyIdList);
            }
        }
    }

    public List<NotifyVo> listNotifyByApprovalId(List<Long> idList) {
        R<List<NotifyVo>> listR = null;
        try {
            listR = notifyClient.listNotifyByApprovalId(idList);
        }catch (Exception e){

        }
        return Objects.isNull(listR)? new ArrayList<>() : listR.getObj();
    }

    private boolean isWait(NotifyVo e) {
        return e.getNotifyProcess().equals(NotifyProcessEnums.WAIT.getType())
            && e.getNotifyType().equals(NotifyTypeEnums.MCN_WAIT.getType());
    }

    public NotifyVo getNextApproval(String approvalTemplateCode) {
        if (MathUtil.isNumeric(approvalTemplateCode)) {
            return notifyClient.getNextApprovingNotify(Long.valueOf(approvalTemplateCode), UserContextHolder.getUserVo().getUserId()).getObj();
        }
        return null;
    }

    public void sendNotify(List<NotifyDTO> notifyList) {
        notifyList.forEach(e -> {
            String message = JsonUtil.obj2String(e);
            log.info("生成对应的待办信息:{}, 租户id:{}", message, TenantContextHolder.getTenantId());
            Message<byte[]> m = MessageBuilder.withPayload(message.getBytes(StandardCharsets.UTF_8))
                    .setHeader(CommonBeanConstants.TENANT_ID, TenantContextHolder.getTenantId()).build();
            SendResult sendResult = rocketTemplate.syncSend(notifyMessageTopic, m);
            log.info("发送MQ消息:{}", JSONObject.toJSONString(sendResult));
        });
    }

    public Boolean urge(DingDTO dingDTO) {
        R<Boolean> result = notifyClient.ding(dingDTO);
        if(result.getCode() != 0) {
            throw new ApiException(new IResultCode() {

                @Override
                public String getMessage() {
                    return result.getMessage();
                }

                @Override
                public int getCode() {
                    return result.getCode();
                }
            });
        }
        return result.getObj();
    }
}
